namespace IMPlant.Core.Web.Control
{
    using IMPlant.Core.Web.Control.GridViewFunction;
    using IMPlant.Core.Web.Control.Helper;
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;

    [DefaultProperty("Text"), ToolboxBitmap(typeof(System.Web.UI.WebControls.GridView)), ToolboxData("<{0}:GridView runat=server></{0}:GridView>")]
    public class GridView : System.Web.UI.WebControls.GridView
    {
        private IMPlant.Core.Web.Control.CascadeCheckboxes _cascadeCheckboxes;
        private string _columnSpan = string.Empty;
        private IMPlant.Core.Web.Control.ComplexHead _complexHead;
        private IMPlant.Core.Web.Control.CustomPagerSettings _customPagerSettings;
        private object _dataSourceObject;
        private List<ExtendFunction> _efs = new List<ExtendFunction>();
        private IMPlant.Core.Web.Control.FixRowColumn _fixRowColumn;
        private string _mergeCells;
        private IMPlant.Core.Web.Control.MouseOver _mouseOver;
        private IMPlant.Core.Web.Control.SmartSorting _smartSorting;
        private static readonly object dataBoundEventKey = new object();
        private static readonly object initPagerEventKey = new object();
        private static readonly object renderBeginEventKey = new object();
        private static readonly object renderEndEventKey = new object();
        private static readonly object rowCreatedCellEventKey = new object();
        private static readonly object rowCreatedDataRowEventKey = new object();
        private static readonly object rowDataBoundCellEventKey = new object();
        private static readonly object rowDataBoundDataRowEventKey = new object();

        [Category("扩展")]
        public event InitPagerHandler InitPager
        {
            add
            {
                base.Events.AddHandler(initPagerEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(initPagerEventKey, value);
            }
        }

        [Category("扩展")]
        public event RenderBeginHandler RenderBegin
        {
            add
            {
                base.Events.AddHandler(renderBeginEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(renderBeginEventKey, value);
            }
        }

        [Category("扩展")]
        public event RenderEndHandler RenderEnd
        {
            add
            {
                base.Events.AddHandler(renderEndEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(renderEndEventKey, value);
            }
        }

        [Category("扩展")]
        public event RowCreateCellHandle RowCreatedCell
        {
            add
            {
                base.Events.AddHandler(rowCreatedCellEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(rowCreatedCellEventKey, value);
            }
        }

        [Category("扩展")]
        public event RowCreatedHandler RowCreatedDataRow
        {
            add
            {
                base.Events.AddHandler(rowCreatedDataRowEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(rowCreatedDataRowEventKey, value);
            }
        }

        [Category("扩展")]
        public event RowDataBoundCellHandler RowDataBoundCell
        {
            add
            {
                base.Events.AddHandler(rowDataBoundCellEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(rowDataBoundCellEventKey, value);
            }
        }

        [Category("扩展")]
        public event RowDataBoundDataRowHandler RowDataBoundDataRow
        {
            add
            {
                base.Events.AddHandler(rowDataBoundDataRowEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(rowDataBoundDataRowEventKey, value);
            }
        }

        [Category("扩展")]
        public event RowsDataBoundHandler RowsDataBound
        {
            add
            {
                base.Events.AddHandler(dataBoundEventKey, value);
            }
            remove
            {
                base.Events.RemoveHandler(dataBoundEventKey, value);
            }
        }

        private void ddl_TextChanged(object sender, EventArgs e)
        {
            this.PageSize = int.Parse(((DropDownList) sender).SelectedValue);
        }

        public void Export(string fileName)
        {
            this.Export(fileName, ExportFormat.CSV);
        }

        public void Export(string fileName, ExportFormat exportFormat)
        {
            this.Export(fileName, exportFormat, Encoding.GetEncoding("GB2312"));
        }

        public void Export(string fileName, ExportFormat exportFormat, Encoding encoding)
        {
            Common.Export(this.GetDataTable(), exportFormat, fileName, encoding);
        }

        public void Export(string fileName, int[] columnIndexList, ExportFormat exportFormat, Encoding encoding)
        {
            Common.Export(this.GetDataTable(), columnIndexList, exportFormat, fileName, encoding);
        }

        public void Export(string fileName, int[] columnIndexList, string[] headers, ExportFormat exportFormat, Encoding encoding)
        {
            Common.Export(this.GetDataTable(), columnIndexList, headers, exportFormat, fileName, encoding);
        }

        private DataTable GetDataTable()
        {
            DataTable table = null;
            if (this._dataSourceObject is DataTable)
            {
                table = (DataTable) this._dataSourceObject;
            }
            else
            {
                if (!(this._dataSourceObject is DataSet))
                {
                    throw new InvalidCastException("若要导出GridView，应保证其数据源为DataTable或DataSet类型");
                }
                table = ((DataSet) this._dataSourceObject).Tables[0];
            }
            if (table == null)
            {
                throw new ArgumentNullException("数据源", "数据源不能为NULL");
            }
            return table;
        }

        private void GridView_PreRender(object sender, EventArgs e)
        {
            if ((this._cascadeCheckboxes != null) && !this.Page.ClientScript.IsClientScriptIncludeRegistered(base.GetType(), "_grid_CascadeCheckbox_ScriptLibrary"))
            {
                this.Page.ClientScript.RegisterClientScriptInclude(base.GetType(), "_grid_CascadeCheckbox_ScriptLibrary", this.Page.ClientScript.GetWebResourceUrl(base.GetType(), "IMPlant.Core.Web.UI.Javascript.CascadeCheckbox.js"));
            }
            HtmlLink child = new HtmlLink();
            child.Attributes["type"] = "text/css";
            child.Attributes["rel"] = "stylesheet";
            child.Attributes["href"] = this.Page.ClientScript.GetWebResourceUrl(base.GetType(), "IMPlant.Core.Web.UI.Css.FixRowColumn.css");
            this.Page.Header.Controls.Add(child);
        }

        protected override void InitializePager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
        {
            columnSpan = GridViewHelper.GetGridViewColumnNum(columnSpan, this._columnSpan);
            if ((this._customPagerSettings != null) && (this._customPagerSettings.PagingMode == PagingMode.Web))
            {
                this.OnInitPager(row, columnSpan, pagedDataSource);
            }
            else
            {
                base.InitializePager(row, columnSpan, pagedDataSource);
            }
        }

        private void ods_Selected(object sender, ObjectDataSourceStatusEventArgs e)
        {
            if (this._dataSourceObject == null)
            {
                this._dataSourceObject = e.ReturnValue;
            }
        }

        protected override void OnDataBound(EventArgs e)
        {
            if (!string.IsNullOrEmpty(this._mergeCells))
            {
                this.OnRowsDataBound(e);
            }
            base.OnDataBound(e);
        }

        protected override void OnInit(EventArgs e)
        {
            base.PreRender += new EventHandler(this.GridView_PreRender);
            if ((this._mouseOver != null) && this._mouseOver.ChangeColor)
            {
                this._efs.Add(new MouseOverFunction());
            }
            if ((this._customPagerSettings != null) && this.AllowPaging)
            {
                this._efs.Add(new CustomPagerSettingsFunction());
            }
            if (!string.IsNullOrEmpty(this._mergeCells))
            {
                this._efs.Add(new MergeCellsFunction());
            }
            if ((this._smartSorting != null) && this.AllowSorting)
            {
                this._efs.Add(new SmartSortingFunction());
            }
            if ((this._complexHead != null) && !string.IsNullOrEmpty(this.ComplexHead.XmlFilePath))
            {
                this._efs.Add(new ComplexHeadFunction());
            }
            if (!string.IsNullOrEmpty(this._columnSpan))
            {
                this._efs.Add(new ColumnSpanFunction());
            }
            if (this._cascadeCheckboxes != null)
            {
                this._efs.Add(new CascadeCheckboxFunction());
            }
            if (this._fixRowColumn != null)
            {
                this._efs.Add(new FixRowColumnFunction());
            }
            foreach (ExtendFunction function in this._efs)
            {
                function.GridView = this;
                function.Complete();
            }
            ObjectDataSource source = this.Parent.FindControl(this.DataSourceID) as ObjectDataSource;
            if (source != null)
            {
                source.Selected += new ObjectDataSourceStatusEventHandler(this.ods_Selected);
            }
            base.OnInit(e);
        }

        protected virtual void OnInitPager(GridViewRow row, int columnSpan, PagedDataSource pagedDataSource)
        {
            InitPagerHandler handler = base.Events[initPagerEventKey] as InitPagerHandler;
            if (handler != null)
            {
                handler(this, row, columnSpan, pagedDataSource);
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (this._dataSourceObject == null)
            {
                this._dataSourceObject = this.DataSource;
            }
            base.OnLoad(e);
        }

        protected virtual void OnRenderBegin(HtmlTextWriter writer)
        {
            RenderBeginHandler handler = base.Events[renderBeginEventKey] as RenderBeginHandler;
            if (handler != null)
            {
                handler(this, writer);
            }
        }

        protected virtual void OnRenderEnd(HtmlTextWriter writer)
        {
            RenderEndHandler handler = base.Events[renderEndEventKey] as RenderEndHandler;
            if (handler != null)
            {
                handler(this, writer);
            }
        }

        protected override void OnRowCreated(GridViewRowEventArgs e)
        {
            if (e.Row.RowType == DataControlRowType.Header)
            {
                this.OnRowCreatedDataRow(e);
            }
            base.OnRowCreated(e);
        }

        protected virtual void OnRowCreatedCell(GridViewTableCell gvtc)
        {
            RowCreateCellHandle handle = base.Events[rowCreatedCellEventKey] as RowCreateCellHandle;
            if (handle != null)
            {
                handle(this, gvtc);
            }
        }

        protected virtual void OnRowCreatedDataRow(GridViewRowEventArgs e)
        {
            RowCreatedHandler handler = base.Events[rowCreatedDataRowEventKey] as RowCreatedHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected override void OnRowDataBound(GridViewRowEventArgs e)
        {
            DataControlRowType rowType = e.Row.RowType;
            for (int i = 0; i < e.Row.Cells.Count; i++)
            {
                GridViewTableCell gvtc = new GridViewTableCell(e.Row.Cells[i], i, e.Row.RowType, e.Row.RowState);
                this.OnRowDataBoundCell(gvtc);
            }
            if (rowType == DataControlRowType.DataRow)
            {
                this.OnRowDataBoundDataRow(e);
            }
            if ((e.Row.RowType == DataControlRowType.Footer) && (((this.PageCount == 1) && (this.PageSize >= this.Rows.Count)) || !this.AllowPaging))
            {
                GridViewRow child = new GridViewRow(-1, -1, DataControlRowType.EmptyDataRow, DataControlRowState.Normal);
                DropDownList list = new DropDownList();
                list.Items.Add(new ListItem("每页显示5条", "5"));
                list.Items.Add(new ListItem("每页显示10条", "10"));
                list.Items.Add(new ListItem("每页显示15条", "15"));
                list.Items.Add(new ListItem("每页显示20条", "20"));
                list.Items.Add(new ListItem("每页显示25条", "25"));
                list.Items.Add(new ListItem("每页显示30条", "30"));
                for (int j = 0; j < list.Items.Count; j++)
                {
                    if (list.Items[j].Value == this.PageSize.ToString())
                    {
                        list.SelectedValue = this.PageSize.ToString();
                        break;
                    }
                }
                list.TextChanged += new EventHandler(this.ddl_TextChanged);
                list.AutoPostBack = true;
                TableCell cell = new TableCell();
                cell.ColumnSpan = this.Rows[0].Cells.Count;
                cell.Text = "当前页共" + this.Rows.Count + "条&nbsp;&nbsp;&nbsp;&nbsp;第1页/共1页&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
                child.Cells.Add(cell);
                this.Controls[0].Controls.AddAt(this.Rows.Count + 1, child);
            }
            base.OnRowDataBound(e);
        }

        protected virtual void OnRowDataBoundCell(GridViewTableCell gvtc)
        {
            RowDataBoundCellHandler handler = base.Events[rowDataBoundCellEventKey] as RowDataBoundCellHandler;
            if (handler != null)
            {
                handler(this, gvtc);
            }
        }

        protected virtual void OnRowDataBoundDataRow(GridViewRowEventArgs e)
        {
            RowDataBoundDataRowHandler handler = base.Events[rowDataBoundDataRowEventKey] as RowDataBoundDataRowHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected virtual void OnRowsDataBound(EventArgs e)
        {
            RowsDataBoundHandler handler = base.Events[dataBoundEventKey] as RowsDataBoundHandler;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        protected override void Render(HtmlTextWriter writer)
        {
            this.OnRenderBegin(writer);
            base.Render(writer);
            this.OnRenderEnd(writer);
        }

        [PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Description("联动复选框"), Category("扩展属性")]
        public virtual IMPlant.Core.Web.Control.CascadeCheckboxes CascadeCheckboxes
        {
            get
            {
                if (this._cascadeCheckboxes == null)
                {
                    this._cascadeCheckboxes = new IMPlant.Core.Web.Control.CascadeCheckboxes();
                }
                return this._cascadeCheckboxes;
            }
        }

        [Category("扩展属性"), Browsable(true), Description("设置需要跨列的列号（从0开始）和跨列的列数的索引（格式为colnum,colSpan;colnum,colSpan......;colnum,colSpan）")]
        public virtual string ColumnSpan
        {
            get
            {
                return this._columnSpan;
            }
            set
            {
                this._columnSpan = value;
            }
        }

        [Description("复杂头功能"), PersistenceMode(PersistenceMode.InnerProperty), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("扩展属性")]
        public virtual IMPlant.Core.Web.Control.ComplexHead ComplexHead
        {
            get
            {
                if (this._complexHead == null)
                {
                    this._complexHead = new IMPlant.Core.Web.Control.ComplexHead();
                }
                return this._complexHead;
            }
            set
            {
                this._complexHead = value;
            }
        }

        [Description("自定义分页样式"), Category("扩展属性"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual IMPlant.Core.Web.Control.CustomPagerSettings CustomPagerSettings
        {
            get
            {
                if (this._customPagerSettings == null)
                {
                    this._customPagerSettings = new IMPlant.Core.Web.Control.CustomPagerSettings();
                }
                return this._customPagerSettings;
            }
            set
            {
                this._customPagerSettings = value;
            }
        }

        [Browsable(false)]
        public object DataSourceObject
        {
            get
            {
                return this._dataSourceObject;
            }
            set
            {
                this._dataSourceObject = value;
            }
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("扩展属性"), Description("固定指定行、指定列"), PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual IMPlant.Core.Web.Control.FixRowColumn FixRowColumn
        {
            get
            {
                if (this._fixRowColumn == null)
                {
                    this._fixRowColumn = new IMPlant.Core.Web.Control.FixRowColumn();
                }
                return this._fixRowColumn;
            }
            set
            {
                this._fixRowColumn = value;
            }
        }

        [Description("需要合并单元格的列的索引（用逗号“,”分隔）"), Browsable(true), Category("扩展属性")]
        public virtual string MergeCells
        {
            get
            {
                return this._mergeCells;
            }
            set
            {
                this._mergeCells = value;
            }
        }

        [Description("鼠标移动时，是否行颜色跟随鼠标变动显示"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), Category("扩展属性"), PersistenceMode(PersistenceMode.InnerProperty)]
        public virtual IMPlant.Core.Web.Control.MouseOver MouseOver
        {
            get
            {
                if (this._mouseOver == null)
                {
                    this._mouseOver = new IMPlant.Core.Web.Control.MouseOver();
                }
                return this._mouseOver;
            }
            set
            {
                this._mouseOver = value;
            }
        }

        [Category("扩展属性"), PersistenceMode(PersistenceMode.InnerProperty), Description("排序功能"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public virtual IMPlant.Core.Web.Control.SmartSorting SmartSorting
        {
            get
            {
                if (this._smartSorting == null)
                {
                    this._smartSorting = new IMPlant.Core.Web.Control.SmartSorting();
                }
                return this._smartSorting;
            }
            set
            {
                this._smartSorting = value;
            }
        }

        public delegate void InitPagerHandler(object sender, GridViewRow row, int columnSpan, PagedDataSource pagedDataSource);

        public delegate void RenderBeginHandler(object sender, HtmlTextWriter writer);

        public delegate void RenderEndHandler(object sender, HtmlTextWriter writer);

        public delegate void RowCreateCellHandle(object sender, GridViewTableCell gvtc);

        public delegate void RowCreatedHandler(object sender, GridViewRowEventArgs e);

        public delegate void RowDataBoundCellHandler(object sender, GridViewTableCell gvtc);

        public delegate void RowDataBoundDataRowHandler(object sender, GridViewRowEventArgs e);

        public delegate void RowsDataBoundHandler(object sender, EventArgs e);
    }
}

